package com.it.reggie.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.it.reggie.common.R;
import com.it.reggie.entity.Employee;
import com.it.reggie.service.EmployeeService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;

@Slf4j
@RestController
@RequestMapping("/employee")
public class EmployeeController {
    //把service接口注入进来
    @Autowired
    private EmployeeService employeeService;
//只要controller有返回值，最终都会封装成R对象进行返回，为了增强通用性，R还设计了泛型（用于传进主体数据data）
    //员工登录
    @PostMapping("/login")//前端发送的是post请求//json数据，接收的时候，需要加注解@RequestBody,封装成employee对象
    public R<Employee> login(HttpServletRequest request ,@RequestBody Employee employee){//HttpServletRequest request因为登录成功之后，
        // 需要把employee对象的ID存到session,表示登录成功，以后如果想获取当前登录用户用request.getsession()获取

        /**
         * 1,将页面提交的密码password进行MD5加密处li
         * 2,根据页面提交的用户名username查询数据库
         * 3,如果没有查询到则返回登录失败结果
         * 4,密码对比，如果不一致则返回失败结果
         * 5,
         * 6,
         *
         * **/
        //1,将页面提交的密码password进行MD5加密处li(提交的password已经封装到employee里面去了)
        String password = employee.getPassword();
        System.out.println("原密码是"+password);
        password = DigestUtils.md5DigestAsHex(password.getBytes());//密码处理//处理完后，赋给自己
        System.out.println("加密后"+password);
        //2,根据页面提交的用户名username查询数据库
        //                  泛型
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper<>();//包装查询对象
        queryWrapper.eq(Employee::getUsername,employee.getUsername());//添加查询条件//床过来的用户名employee.getUsername()
        Employee emp = employeeService.getOne(queryWrapper);//因为数据库里已经对username字段做了一个唯一的约束，加了Unique索引约束，用getOne查出唯一的数据
        //3,如果没有查询到则返回登录失败结果
        if(emp==null){
            System.out.println("登录失败111");
            return R.error("登录失败(没有这个人)");
        }
        //4,密码对比，如果不一致则返回失败结果

        if(!emp.getPassword().equals(password)){
            System.out.println("登录失败222");
            return R.error("登录失败(密码错了)");
        }
        //5,查看员工状态，如果为已境用状态，则返回员工已禁用结果
        if(emp.getStatus()==0)//0表示禁用，1表示可用
        {
            System.out.println("账号禁用333");
            return R.error("账号已禁用");
//禁用弹窗之后，右键检查，Network,login,Response可以查看到将返回的R对象转成json数
// 据{"code":0,"msg":"账号已禁用","data":null,"map":{}}
        }
        //6，登录成功，将用户id存入Session并返回登录成功结果
        request.getSession().setAttribute("employee",emp.getId());//点击退出按钮的时候，需要清理Session中的用户id
        //                                        key         value
        return R.success(emp);//47从数据库查出来的对象
    }
    //员工退出
    @PostMapping("/logout")
    public R<String> logout(HttpServletRequest request){
        //清理Session中保存的当前员工的id
        request.getSession().removeAttribute("employee");//参考68行的相反操作
        return R.success("退出成功");
    }

    //新增员工
    @PostMapping
    public R<String> save(HttpServletRequest request,@RequestBody Employee employee){
        log.info("新增员工，员工信息：{}",employee.toString());

        //设置初始密码123456，用md5进行加密
        employee.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));//变成byte数组

        //employee.setCreateTime(LocalDateTime.now());
        //employee.setUpdateTime(LocalDateTime.now());
        //登录成功之后已经把用户id放到session里面了//此时可以通过request得到一个session,以获得当前登录用户的id
        //Long empId = (Long) request.getSession().getAttribute("employee");//当时69行放进去的就是emp.getId()...long型的id
        //           此处要强转一下类型，因为getAttribute()方法返回的都是Object类型

        //employee.setCreateUser(empId);
        //employee.setUpdateUser(empId);

        employeeService.save(employee);//把这个对象存进去
//save方法继承自mybatis-plus的父接口IService（看看application.yml文件）,可以直接调用
        return R.success("新增员工成功");
    }

    //员工信息分页查询
    //创建一个controller方法，接收页面发送的请求并且接收参数（page,pageSize,name）
    @GetMapping("/page")
    public R<Page> page(int page,int pageSize,String name){
        log.info("page = {},pageSize = {}, name = {}",page,pageSize,name);
        //                                    搜索框搜索时要用到
     // 由mybatis-plus封装的类，分页查询的时候也会返回这个对象，Page类中的records放的是当前这一页要展示的列表数据(放在List<>里面)，total(总的条数)
    //Page类中的records和total是list.html页面145行需要的数据

        //构造分页构造器             1     10
        Page pageInfo = new Page(page,pageSize);
        //构建条件构造器（动态封装传过来的过滤条件）
        // 通过定义泛型类型，一段代码可以用于不同的数据类型，使代码更加灵活和高效。
        LambdaQueryWrapper<Employee> queryWrapper = new LambdaQueryWrapper();
        //添加过滤条件.eq最终反馈到数据库就是where name=?，.like最终反馈到数据库就是where name like '%XXX%';
        //               当'name'(将用于like查询的值)不=空的时候，条件Employee::getName,name才添加进去
        queryWrapper.like(StringUtils.isNotEmpty(name),Employee::getName,name);//'queryWrapper'是一个帮助构造数据库查询的对象。？？？？？
//       是org.apache.commons.lang的StringUtils才有isNotEmpty()方法///类名::方法名
          //添加排序条件  //   使用Employee里的updateTime来排序
        queryWrapper.orderByDesc(Employee::getUpdateTime);
        //执行查询                   // 条件构造器
        employeeService.page(pageInfo,queryWrapper);//page方法已经已经继承了IService,已经提供了分页查询方法，只需要把Page对象和queryWrapper对象构造好，传给他，自己就会进行分页查询
     //条件构造器传进去之后，不需要去返回，因为把pageInfo传进去之后，在page内部，就会把查出来的数据进行封装，最终封装给page里的records,total。。
        return R.success(pageInfo);
    }
//@RequestBody用于指示在HTTP请求中传递的数据应该绑定到方法参数。它通常用于接收请求体中的数据（如JSON或XML），并将其映射到后端的对象。
    //根据id修改员工信息
    @PutMapping
    public R<String> update(HttpServletRequest request,@RequestBody Employee employee){
//‘@RequestBody’注释表明‘Employee’对象将从请求体中反序列化，通常采用JSON或XML格式。
        log.info("修改员工信息：："+employee.toString());

        long id = Thread.currentThread().getId();
        log.info("当前线程id为：{}",id);

       // Long empId = (Long)request.getSession().getAttribute("employee");//‘request’对象表示服务器正在处理的当前HTTP请求
       // employee.setUpdateTime(LocalDateTime.now());//获取这次修改的时间
       // employee.setUpdateUser(empId);//谁改的，当前登录用户//可以通过session来获取
        employeeService.updateById(employee);//updateById继承自父接口IService(由mybatis-plus提供)
        return R.success("员工信息修改成功");
    }
    //根据id查询员工信息
    @GetMapping("/{id}")//   路径变量//说明id变量是在整个请求路径里
    public R<Employee> getById(@PathVariable Long id){
        log.info("根据id查询员工信息");
        Employee employee = employeeService.getById(id);
        if(employee!=null){//查出来才返回
            return R.success(employee);//employee对象在R里转成了json
        }
       return R.error("没有查询到这个员工");
    }
}
